/**
 * 
 */
package research.sbookmarking;

import java.util.*;
import java.io.*;

/**
 * This class is a wrapper for the data mined from Connotea.org. 
 * <P>
 * @author <A HREF="mailto:aatleung@gmail.com">Albert Leung</a>
 * @version 1.0
 */

public class DataContainer implements Serializable{

	private static final long serialVersionUID=1L;
	
	// contains the type of query performed
	private String queryName = null;
	
	// contains the list of tags per user per URL 
	private HashMap<String,Object> urlUserTags = new HashMap<String,Object>();
	
	// contains the list of data from query of Connotea.org
	private List<? extends Object> queryResults = null;
	
	/* contains a list of frequency of bookmarks and tags used in the data mined 
	 * from Connotea.org
	 * [0] - bookmarks
	 * [1] - tags
	private List repeats = null;
	 */

	/**
	 * Create a new DataContainer instance using the supplied list of
	 * Bookmarks/Posts.
	 * <p>
	 * @param queryResult the list of unique bookmarks/posts gather from the data mining 
	 * 				 of Connotea.
	 */
	public DataContainer (String queryName, List<Object> queryResults) {
		setQueryName (queryName);
		setQueryResults (queryResults);
		
	}
	
	public DataContainer (String queryName) {
		setQueryName (queryName);
	}
	
	protected List <String> removeDoubles(Iterator<String> list){
		ArrayList<String> uniques = new ArrayList<String>();
		while (list.hasNext()){
			String item = list.next();
			if (uniques.contains(item)!=true){
				uniques.add(item);
			}
		}
		
		return uniques;
	}
	
	@SuppressWarnings("unchecked")
	protected List <String> removeDuplicates(Iterator<Object> hashMaps){
		ArrayList<String> uniques = new ArrayList<String>();
		while (hashMaps.hasNext()){
			HashMap<String,Object> aHashMap = (HashMap<String,Object>)hashMaps.next();
			Iterator<String> keys = aHashMap.keySet().iterator();
			AppController.getInstance().copy(uniques, removeDoubles(keys).iterator());
		}
		
		return uniques;
	}
	
	public List <String> getUniqueUsers() {
		ArrayList<Object> userHashMaps = new ArrayList<Object>(getUrlUserTags().values());
		return removeDuplicates(userHashMaps.iterator());
	}

	@SuppressWarnings("unchecked")
	public List<String> getTags() {
		ArrayList<Object> tmp = new ArrayList<Object>(getUrlUserTags().values());
		HashMap<Object,Object> hashMaps = new HashMap<Object,Object>();
		for (int i=0; i< tmp.size(); i++){
			hashMaps.putAll((Map<? extends Object, ? extends Object>) tmp.get(i));
		}
		tmp = new ArrayList<Object>(hashMaps.values());
		hashMaps.clear();
		for (int i=0; i< tmp.size(); i++){
			hashMaps.putAll((Map<? extends Object, ? extends Object>) tmp.get(i));
		}
		
		return this.removeDoubles(this.convertToList(new ArrayList(hashMaps.keySet())).iterator());
	}

	/**
	 * Saves the list of bookmarks, posts, or tags that was mined from Connotea.org.
	 * <P>
	 * @param className the type of query perfomed on Connotea.org.
	 * @param queryResult the list of unique bookmarks/posts gather from the data mining 
	 * 					  of Connotea.
	 */
	public final void setQueryResults (List<? extends Object> queryResult){
		queryResults=queryResult;
	}
	
	/**
	 * Returns the list of unique bookmarks/posts that was mined from Connotea.org.
	 * <p>
	 * @return a list of unique bookmarks/posts. 
	 */
	@SuppressWarnings("unchecked")
	public List<Object> getQueryResults() {
		return (List<Object>) queryResults;
	}
	
	public String getQueryName() {
		return queryName;
	}


	public void setQueryName(String queryName) {
		this.queryName = queryName;
	}


	public List<String> getURL(){
		return new ArrayList<String>(getUrlUserTags().keySet());
	}
	
	private List<String> combineList(List<String> list1, List<String> list2){
		if (list1==null){
			return list2;
		}
		
		for (int i=0; i < list2.size(); i++){
			if (list1.contains(list2.get(i))!= true){
				//list1.add(list2.get(i));
				String tmp = list2.get(i);
				list1.add(tmp);
			}
		}
		
		return list1;
	}
	
	private List<String> convertToList(ArrayList<List<String>> arrayList){
		ArrayList<String> tmp = new ArrayList<String>();
		for (int i=0; i<arrayList.size(); i++){
			AppController.getInstance().copy(tmp, (arrayList.get(i)).iterator());
		}
		
		return tmp;
	}
	
	@SuppressWarnings("unchecked")
	public HashMap<String, Object> getUserTags() {
		HashMap<String,Object> userTags = new HashMap<String,Object>(); 
		ArrayList<Object> userHashMaps = new ArrayList<Object>(getUrlUserTags().values());
		for (int i = 0; i < userHashMaps.size(); i++){
			HashMap<String,Object> userHashMap = (HashMap<String,Object>)userHashMaps.get(i);
			Iterator<String> users = userHashMap.keySet().iterator();
			while (users.hasNext()){
				String user = users.next();
				HashMap <List<String>,Object> tagHashMap = (HashMap<List<String>,Object>)userHashMap.get(user); 
				List<String> tagsList = convertToList(new ArrayList<List<String>>(tagHashMap.keySet()));
				List<String> tags;
				if (userTags.containsKey(user)){
					tags = (List<String>) userTags.get(user);
					tags = combineList(tags,tagsList);
				}
				else {
					tags = tagsList;
				}
				userTags.put(user, tags);
			}
		}
		return userTags;
	}

	public HashMap<String, Object> getUrlUserTags() {
		return urlUserTags;
	}


	public void setUrlUserTags(HashMap<String, Object> urlUserTags) {
		this.urlUserTags = urlUserTags;
	}
}
